﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonLib {
    // tga
    // http://www.is.oit.ac.jp/~whashimo/server/~whashimo/Article/OpenGL/Chapter7/tgaform.pdf
    public class Texture {
        private Vector3c[] pixels;
        private int width;
        private int height;

        public Texture(string file) {
            byte[] data = System.IO.File.ReadAllBytes(file);
            this.width = data[0x0c] + data[0x0d] * 256;
            this.height = data[0x0e] + data[0x0f] * 256;
            int bpp = data[0x10];

            initialize(data, bpp, 0x12, this.width * this.height);
        }

        public Vector3c getTexel(double au, double av) {
            double fu = (au + 1000) * width;
            double fv = (av + 1000) * height;
            int iu = (int)fu;
            int iv = (int)fv;
            int u1 = iu % width;
            int v1 = iv % height;
            int u2 = (iu + 1) % width;
            int v2 = (iv + 1) % height;

            double fracu = fu - iu;
            double fracv = fv - iv;
            // (u, v)
            // w1 w2
            // w3 w4
            double w1 = (1 - fracu) * (1 - fracv);
            double w2 = fracu * (1 - fracv);
            double w3 = (1 - fracu) * fracv;
            double w4 = fracu * fracv;

            Vector3c result = pixels[u1 + v1 * width];
            result.mul(w1);
            result.mac(w2, pixels[u2 + v1 * width]);
            result.mac(w3, pixels[u1 + v2 * width]);
            result.mac(w4, pixels[u2 + v2 * width]);
            return result;
        }

        private void initialize(byte[] data, int bpp, int start, int length) {
            this.pixels = new Vector3c[length];
            double rdepth = 1.0 / 256;

            switch (bpp) {
                case 24:
                    for (int i = 0; i < length; i++) {
                        int index = start + i * 3;
                        pixels[i].set(data[index + 2], data[index + 1], data[index]);
                        pixels[i].mul(rdepth);
                    }
                    break;
                case 32:
                    for (int i = 0; i < length; i++) {
                        int index = start + i * 4;
                        pixels[i].set(data[index + 2], data[index + 1], data[index]);
                        pixels[i].mul(rdepth);
                    }
                    break;
                default:
                    System.Diagnostics.Debug.Fail("This TGA is not supported");
                    break;
            }

        }
    }
}
